#include "myStdio.h"

FILE_ *fopen_(const char* path_name, const char* mode)
{
  int flag = 0;
  int defaultmode = 0666;
  if(strcmp(mode,"r") == 0)
  {
    flag |= O_RDONLY ;
  }
  else if(strcmp(mode,"w") == 0)
  {
    flag |= O_WRONLY | O_TRUNC | O_CREAT;
  }
  else if(strcmp(mode,"a") == 0)
  {
    flag |= O_WRONLY | O_APPEND | O_CREAT;
  }
  else 
  {
    //
  }
  int fd = 0;
  if(flag & O_RDONLY ) fd = open(path_name, flag);
  else fd = open(path_name, flag, defaultmode);

  if(fd < 0)
  {
    const char* msg = strerror(errno);
    write(1, msg, strlen(msg));
    return NULL;
  }
  
  FILE_ *fp =(FILE_*)malloc(sizeof(FILE_));
  assert(fp != NULL);
  fp->flags = SYNC_LINE;//默认为行刷新
  fp->fileno = fd;
  fp->size = 0;
  fp->cap = SIZE;
  memset(fp->buffer, 0 ,SIZE);
  
  return fp;
}

void fwrite_(const char* ptr, int num, FILE_ * fp)
{
  // 1 将数据写入到缓冲区中
  memcpy(fp->buffer+fp->size, ptr, num);//这里不考虑缓冲区溢出的问题
  fp->size += num;
  // 2 判断是否刷新
  if(fp->flags & SYNC_NOW)
  {
    write(fp->fileno, fp->buffer, fp->size);
    fp->size = 0;//清空缓冲区,惰性释放，这样后来再写入的时候就能从0开始覆盖
  }
  else if (fp->flags & SYNC_FULL) 
  {
    if(fp->size >= fp->cap)
    {
      write(fp->fileno, fp->buffer, fp->size);
      fp->size = 0;//清空缓冲区,惰性释放，这样后来再写入的时候就能从0开始覆盖
    }
  }
  else if(fp->flags & SYNC_LINE)
  {
    if(fp->buffer[fp->size - 1] == '\n')  //abc/ndef,这种情况暂不考虑
    {
      write(fp->fileno, fp->buffer, fp->size);
      fp->size = 0;//清空缓冲区,惰性释放，这样后来再写入的时候就能从0开始覆盖
    }
  }
  else 
    ;
} 

void fflush_(FILE_ *fp)
{
  if(fp->size > 0) write(fp->fileno, fp->buffer, fp->size);
  fsync(fp->fileno);//让OS强制将数据刷新到外设中
  fp->size = 0;
}

void fclose_(FILE_ * fp)
{
  fflush_(fp);
  close(fp->fileno);
}
